package com.blacktech.dbu.core.advice;

import com.blacktech.dbu.core.annotation.IgnoreResponseWrap;
import com.blacktech.dbu.core.response.ApiResponse;
import com.blacktech.dbu.core.response.PageResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 全局响应处理器
 * 自动将Controller返回值包装为统一响应格式
 * 已移除Spring Data REST，简化了判断逻辑
 *
 * @author Yanyunsong
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.blacktech.dbu")
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 检查是否需要包装响应
        Class<?> containingClass = returnType.getContainingClass();

        // 如果类或方法上有@IgnoreResponseWrap注解，则不包装
        if (containingClass.isAnnotationPresent(IgnoreResponseWrap.class)) {
            return false;
        }

        if (returnType.hasMethodAnnotation(IgnoreResponseWrap.class)) {
            return false;
        }

        // 排除代理类
        if (containingClass.getName().contains("$") ||
            containingClass.getName().contains("Proxy") ||
            containingClass.getName().contains("_")) {
            return false;
        }

        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                Class<? extends HttpMessageConverter<?>> converterType,
                                ServerHttpRequest request, ServerHttpResponse response) {

        // 如果已经是统一响应格式，直接返回
        if (body instanceof ApiResponse) {
            return body;
        }

        // 处理String类型的特殊情况
        if (body instanceof String) {
            return ApiResponse.success(body);
        }

        // 包装其他类型
        return wrapResponse(body, returnType);
    }

    /**
     * 包装响应数据
     */
    private Object wrapResponse(Object body, MethodParameter returnType) {
        if (body == null) {
            return ApiResponse.success();
        }

        // 处理PageResponse类型（已经是完整的分页响应）
        if (body instanceof PageResponse<?> pageResponse) {
            return ApiResponse.success(pageResponse);
        }

        // 处理Spring Data Page对象
        if (body instanceof Page<?> page) {
            return ApiResponse.success(PageResponse.of(page));
        }

        // 处理其他类型
        return ApiResponse.success(body);
    }
}